package Model;

import Componenten.LocalTypes;
import java.util.HashSet;
import java.util.Set;

/**
 * Klasse die een element op een vak representeert
 * @author Bram Slob en Roderick van Seijen
 */
public class Element implements LocalTypes {
    
    
    private ElementType tElementType;
    private Vak huidigVak;
    
    /**
     * Constructor voor Element
     * @param et type van het nieuwe element
     * @param v vak waarop het nieuwe element komt te staan
     */
    public Element(ElementType et, Vak v)
    {
        huidigVak = v;
        tElementType = et;
    }

    public void setElementType(ElementType tElementType) {
        this.tElementType = tElementType;
    }
    
    /**
     * @return  Vak waarop het element staat
     */
    public Vak getHuidigVak(){
        return huidigVak;
    }
    
    /**
     * @return type van het element
     */
    public ElementType getElementType()
    {
        return tElementType;
    }
    
    /**
     * Probeer het element 1 vak in de gegeven richting te bewegen.
     * @param r  Beweegrichting
     * @param m  Speelmodus (kind / volwassene)
     * @return   Set met vakken waar een beweging op plaats gevonden heeft.
     *           Lege Set indien de gewenste beweging niet mogelijk is.
     */
    public Set<Vak> beweeg(Richting r, Modus m){
        

        Set<Vak> vakken = new HashSet();
        Vak buurVak = huidigVak.getBuurvak(r);
        
        if (buurVak != null){
            
            Element buurElement = buurVak.getElement();
            
            if (buurElement == null){
                // als buurvak leeg is
                switch (tElementType) {
                    case LEGE_DOOS:
                    case VOLLE_DOOS:
                    case DOOS:
                    case SPELER:
                    case HULPSTUK:
                        vakken.addAll(voerBewegingUit(buurVak));
                        break;
                }
            } else {
                // als buurvak niet leeg is
                switch (tElementType) {
                    case VOLLE_DOOS:
                    case DOOS:
                        if (m == Modus.KIND){
                            vakken = zetInBeweging(r, m, buurVak);
                        }
                        break;
                    case LEGE_DOOS:
                        if (buurElement.getElementType() == ElementType.HULPSTUK) {
                            buurVak.setElement(null);
                            this.setElementType(ElementType.VOLLE_DOOS);
                            vakken.addAll(voerBewegingUit(buurVak));
                        } else if (m == Modus.KIND) {
                            
                            vakken = zetInBeweging(r, m, buurVak);
                        }
                        break;
                        
                    case HULPSTUK:
                        if (buurElement.getElementType() == ElementType.LEGE_DOOS) {
                            buurVak.setElement(null);
                            this.setElementType(ElementType.VOLLE_DOOS);
                            vakken.addAll(voerBewegingUit(buurVak));
                        } else if (m == Modus.KIND) {
                            vakken = zetInBeweging(r, m, buurVak);
                        }
                        break;
                        
                    case SPELER:
                        vakken = zetInBeweging(r, m, buurVak);
                        break;
                }
            }
        }   
        return vakken;
    }
    
    /**
     * Geef het buurelement de opdracht om te gaan bewegen
     * @param r  Beweegrichting
     * @param m  Speelmodus (kind / volwassene)
     * @return   Set met vakken waar een beweging op plaats gevonden heeft.
     *           Lege Set indien de gewenste beweging niet mogelijk is.
     */
    private Set<Vak> zetInBeweging(Richting r, Modus m, Vak buurVak){
        
        Set<Vak> vakken = new HashSet();
        Element buurElement = buurVak.getElement();
        
        if(buurElement != null){
            Set<Vak> vakkenBuur = buurElement.beweeg(r, m);

            if (!vakkenBuur.isEmpty()) {
                vakken.addAll(vakkenBuur);
                vakken.addAll(voerBewegingUit(buurVak));
            }
        }
  
        return vakken;
    }
    
    /**
     * Beweeg een element naar het gegeven buurVak en geef de vakken terug waar een beweging op plaatsgevonden heeft.
     * @param buurVak Het buurvak waar het element naar toe bewogen dient te worden
     * @return   Set met vakken waar een beweging op plaats gevonden heeft.
     */
    private Set<Vak> voerBewegingUit(Vak buurVak){
        Set<Vak> vakken = new HashSet();

        vakken.add(huidigVak);
        vakken.add(buurVak);
        buurVak.setElement(this);
        huidigVak.setElement(null);
        huidigVak = buurVak;
        //System.out.println("Object " + this.ElementType.toString() + " verschoven naar (" + this.huidigVak.getPositie().getX() + "," + this.huidigVak.getPositie().getY() + ")");
        return vakken;
    }
       
}
